package com.zhiche.wms.service.opbaas.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.common.collect.Maps;
import com.zhiche.wms.configuration.MyConfigurationProperties;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.InterfaceEventEnum;
import com.zhiche.wms.core.supports.enums.NodeOptionEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.HttpClientUtil;
import com.zhiche.wms.core.utils.HttpRequestUtil;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.opbaas.OpTaskMapper;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.model.opbaas.OpDeliveryPoint;
import com.zhiche.wms.domain.model.opbaas.OpTask;
import com.zhiche.wms.domain.model.opbaas.StatusLog;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.otm.OtmShipment;
import com.zhiche.wms.domain.model.sys.SysConfig;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.base.PageVo;
import com.zhiche.wms.dto.base.ResultDTOWithPagination;
import com.zhiche.wms.dto.opbaas.paramdto.TaskControllerParamDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskDetailResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskReleaseResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskResultDTO;
import com.zhiche.wms.service.common.IntegrationService;
import com.zhiche.wms.service.constant.Task;
import com.zhiche.wms.service.dto.OTMEvent;
import com.zhiche.wms.service.opbaas.ExceptionToOTMService;
import com.zhiche.wms.service.opbaas.IDeliveryPointService;
import com.zhiche.wms.service.opbaas.IStatusLogService;
import com.zhiche.wms.service.opbaas.ITaskService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.otm.IOtmShipmentService;
import com.zhiche.wms.service.outbound.impl.OutboundNoticeHeaderServiceImpl;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.sys.SysConfigService;
import com.zhiche.wms.service.utils.BusinessNodeExport;
import com.zhiche.wms.service.utils.CommonMethod;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 作业任务 服务实现类
 * </p>
 *
 * @author user
 * @since 2018-05-24
 */
@Service
public class TaskServiceImpl extends ServiceImpl<OpTaskMapper, OpTask> implements ITaskService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OutboundNoticeHeaderServiceImpl.class);


    @Autowired
    private IUserService userService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private BusinessNodeExport nodeExport;
    @Autowired
    private IntegrationService integrationService;
    @Autowired
    private IStatusLogService statusLogService;
    @Autowired
    private IDeliveryPointService deliveryPointService;
    @Autowired
    private SnowFlakeId snowFlakeId;
    @Autowired
    private ExceptionToOTMService exceptionToOTMService;
    @Autowired
    SysConfigService sysConfigService;
    @Autowired
    private OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    private IOtmOrderReleaseService otmOrderReleaseService;
    @Autowired
    private IOtmShipmentService shipmentService;

    @Autowired
    private MyConfigurationProperties properties;

    /**
     * <p>
     * 查询对应的订单信息,支持订单号/车架号查询模糊匹配
     * </p>
     *
     * @param dto 参数封装
     */
    @Override

    public List<TaskResultDTO> queryTaskInfo(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        String queryParam = dto.getQueryParam();
        if (StringUtils.isBlank(queryParam)) {
            throw new BaseException("查询车架号或订单号不能为空!");
        }
        //taskType任务类型，0或者null代表全部的任务类型，10/20/30代表寻移提
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            //查询指令信息(异常登记列表)
            return queryInfoQuick(dto);
        } else {
            //查询任务信息
            return queryTasks(dto, loginUser);
        }
    }

    private List<TaskResultDTO> queryInfoQuick(TaskControllerParamDTO dto) {
        String queryParam = dto.getQueryParam();
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .like("vin", queryParam, SqlLike.DEFAULT)
                .or()
                .like("cus_order_no", queryParam)
                .or()
                .eq("qr_code", queryParam)
                .orderBy("gmt_create", false)
                .orderBy("id", false);
        if (StringUtils.isNotBlank(dto.getPointId())){
            OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(dto.getPointId());
            reEW.andNew().eq("origin_location_gid",opDeliveryPoint.getCode());
        }
        Page<OtmOrderRelease> page = new Page<>();
        Page<OtmOrderRelease> releasePage = releaseService.selectPage(page, reEW);
        List<OtmOrderRelease> releases = releasePage.getRecords();
        if (CollectionUtils.isEmpty(releases)) {
            throw new BaseException("未查询到" + queryParam + "的运单信息");
        }
        ArrayList<TaskResultDTO> result = Lists.newArrayList();
        for (OtmOrderRelease re : releases) {
            TaskResultDTO taskResultDTO = buildTaskDetail(re);
            taskResultDTO.setTaskType(dto.getTaskType());
            result.add(taskResultDTO);
        }
        return result;
    }

    private TaskResultDTO buildTaskDetail(OtmOrderRelease re) {
        TaskResultDTO taskResultDTO = new TaskResultDTO();
        taskResultDTO.setReleaseId(String.valueOf(re.getId()));
        taskResultDTO.setVehicle(re.getStanVehicleType());
        taskResultDTO.setDispatchNo(re.getShipmentGid());
        taskResultDTO.setOrderReleaseGid(re.getReleaseGid());
        taskResultDTO.setOriginCode(re.getOriginLocationGid());
        taskResultDTO.setOriginName(re.getOriginLocationName());
        taskResultDTO.setDestCode(re.getDestLocationGid());
        taskResultDTO.setDestName(re.getDestLocationName());
        taskResultDTO.setVin(re.getVin());
        taskResultDTO.setOrderNo(re.getCusOrderNo());
        taskResultDTO.setWayBillNo(re.getReleaseGid());
        taskResultDTO.setQrCode(re.getQrCode());
        taskResultDTO.setStanVehicleType(re.getStanVehicleType());
        return taskResultDTO;
    }

    private List<TaskResultDTO> queryTasks(TaskControllerParamDTO dto,
                                           User loginUser) {
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        HashMap<String, Object> params = Maps.newHashMap();
        String queryParam = dto.getQueryParam();
        params.put("queryParam", queryParam);
        params.put("userCode", userCode);
        params.put("userId", loginUser.getId());
        params.put("cancel", TableStatusEnum.STATUS_50.getCode());
        params.put("start", 0);
        params.put("end", 10);
        params.put("taskType", dto.getTaskType());
        /*if(queryParam.length() >5){
            params.put("likeVin", "%" + queryParam.substring(queryParam.length()-5));
        }else {
            params.put("likeVin", "%" + queryParam);
        }*/
        params.put("likeVin", "%" + queryParam);
        params.put("orderBy", "a.gmt_create desc,a.id desc,c.type asc");
        //首页查询用户对应起运地下的所有运单
        List<TaskResultDTO> dtoList = baseMapper.queryTaskInfo(params);
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new BaseException("未查询到对应的运单信息!");
        }
        return dtoList;
    }

    /**
     * <p>
     * app首页--任务列表查询
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public ResultDTOWithPagination<List<TaskResultDTO>> queryTaskList(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        String taskType = dto.getTaskType();
        int pageNo = dto.getPageNo();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        if (pageNo < 1) {
            throw new BaseException("页码不正确!");
        }
        //查用户发车点配置-->运单-->任务
        //根据类型分页返回
        HashMap<String, Object> queryParam = Maps.newHashMap();
        queryParam.put("status10", TableStatusEnum.STATUS_10.getCode());
        queryParam.put("status20", TableStatusEnum.STATUS_20.getCode());
        queryParam.put("status50", TableStatusEnum.STATUS_50.getCode());
        queryParam.put("userCode", userCode);
        queryParam.put("userId", loginUser.getId());
        queryParam.put("taskType", taskType);
        queryParam.put("start", dto.getStartIndex());
        queryParam.put("end", dto.getPageSize());
        queryParam.put("orderBy", "c.gmt_modified desc");
        queryParam.put("pointId", dto.getPointId());
        List<TaskResultDTO> taskResultDTOList = baseMapper.queryTaskList(queryParam);
        if (CollectionUtils.isEmpty(taskResultDTOList)) {
            throw new BaseException("未查询到用户:" + userCode + "此项任务信息");
        }
        int count = baseMapper.countTaskList(queryParam);
        ResultDTOWithPagination<List<TaskResultDTO>> pagination = new ResultDTOWithPagination<>();
        PageVo pageVo = new PageVo();
        pageVo.setPageNo(dto.getPageNo());
        pageVo.setTotalRecord(count);
        pageVo.setPageSize(dto.getPageSize());
        pagination.setPageVo(pageVo);
        pagination.setData(taskResultDTOList);
        return pagination;
    }


    /**
     * 使用page封装查询数据
     */
    @Override
    public Page<TaskResultDTO> queryTaskPage(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        //根据类型分页返回
        Page<TaskResultDTO> page = new Page<>();
        EntityWrapper<TaskResultDTO> ew = new EntityWrapper<>();
        ew.eq("type", taskType)
                .eq("user_id", loginUser.getId())
                .ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .eq("taskStatus", TableStatusEnum.STATUS_10.getCode())
                .or()
                .eq("taskStatus", TableStatusEnum.STATUS_20.getCode())
                .orderBy("gmt_create", false)
                .orderBy("taskId", false);
        page.setCurrent(dto.getPageNo());
        page.setSize(dto.getPageSize());
        List<TaskResultDTO> list = baseMapper.queryTaskPage(page, ew);
        page.setRecords(list);
        return page;
    }


    /**
     * <p>
     * 如果是通过快速附码进入,taskType -0 关联指令节点
     * 扫码获取任务详情,任务顺序展示
     * </p>
     *
     * @param dto 参数封装
     * @return 返回值
     */
    @Override
    public TaskDetailResultDTO getDetailByScan(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        String queryParam = dto.getQueryParam();
        if (StringUtils.isBlank(queryParam)) {
            throw new BaseException("查询车架号或订单号不能为空!");
        }
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            TaskDetailResultDTO taskDetailResultDTO = queryQuickScan(dto);
            String send = exceptionToOTMService.isSend(taskDetailResultDTO.getVin(), taskDetailResultDTO.getOriginName());
            if (StringUtils.isNotBlank(send)){
                taskDetailResultDTO.setIsCanSend(send);
            }
            return taskDetailResultDTO;
        } else {
            TaskDetailResultDTO taskDetailResultDTO = queryTaskScan(dto, loginUser);
            String send = exceptionToOTMService.isSend(taskDetailResultDTO.getVin(), taskDetailResultDTO.getOriginName());
            if (StringUtils.isNotBlank(send)){
                taskDetailResultDTO.setIsCanSend(send);
            }
            return taskDetailResultDTO;
        }
    }

    private TaskDetailResultDTO queryQuickScan(TaskControllerParamDTO dto) {
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
        String queryParam = dto.getQueryParam();
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .like("vin", queryParam, SqlLike.DEFAULT)
                .or()
                .eq("cus_order_no", queryParam)
                .or()
                .eq("qr_code", queryParam)
                .orderBy("gmt_create", false)
                .orderBy("id", false);
        if (StringUtils.isNotBlank(dto.getPointId())){
            OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(dto.getPointId());
            reEW.eq("origin_location_gid",opDeliveryPoint.getCode());
        }
        List<OtmOrderRelease> releases = releaseService.selectList(reEW);
        if (CollectionUtils.isEmpty(releases)) {
            throw new BaseException("未查询到" + queryParam + "的运单信息");
        }
        OtmOrderRelease release = releases.get(0);
        TaskDetailResultDTO result = new TaskDetailResultDTO();
        result.setQrCode(release.getQrCode());
        result.setReleaseId(String.valueOf(release.getId()));
        result.setVehicle(release.getStanVehicleType());
        result.setDispatchNo(release.getShipmentGid());
        result.setOrderReleaseGid(release.getReleaseGid());
        result.setOriginCode(release.getOriginLocationGid());
        result.setOriginName(release.getOriginLocationName());
        result.setDestCode(release.getDestLocationGid());
        result.setDestName(release.getDestLocationName());
        result.setVin(release.getVin());
        result.setOrderNo(release.getCusOrderNo());
        result.setWayBillNo(release.getReleaseGid());
        result.setStanVehicleType(release.getStanVehicleType());
        result.setOtmStatus(release.getStatus());
        result.setOrderDestAddress(release.getOrderDestAddress());
        result.setTaskType(dto.getTaskType());
        result.setModifiedVehicleType(release.getModifiedVehicleType());
        return result;
    }

    private TaskDetailResultDTO queryTaskScan(TaskControllerParamDTO dto, User loginUser) {
        String queryParam = dto.getQueryParam();
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("queryParam", queryParam);
        params.put("likeVin", "%" + queryParam + "%");
        params.put("userCode", userCode);
        params.put("userId", loginUser.getId());
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("orderBy", "a.gmt_create desc,a.id desc");
        params.put("start", 0);
        params.put("end", 1);
        //首页查询用户对应起运地下的所有运单
        List<TaskReleaseResultDTO> dtoList = releaseService.queryRealeaseInfo(params);
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new BaseException("未查询到对应的运单信息!");
        }
        TaskReleaseResultDTO resultDTO = dtoList.get(0);
        String locationGid = resultDTO.getSourceLocationGid();
        if (StringUtils.isBlank(locationGid)) {
            throw new BaseException("该车辆:" + resultDTO.getAttribute7() + "发车点编码为空!");
        }
        if (resultDTO.getId() == null) {
            throw new BaseException("该用户CODE:" + userCode + "未关联发车点:" + locationGid);
        }
        //查询任务详情,及关联的二维码
        HashMap<String, Object> map = Maps.newHashMap();
        map.put("releaseGid", resultDTO.getOrderReleaseGid());
        map.put("status50", TableStatusEnum.STATUS_50.getCode());
        map.put("userId", loginUser.getId());
        map.put("start", 0);
        map.put("end", 10);
        map.put("orderBy", "b.type,b.status");
        map.put("pointId", dto.getPointId());
        map.put("taskType", dto.getTaskType());
        List<TaskDetailResultDTO> result = baseMapper.getTaskDetailScan(map);
        if (CollectionUtils.isNotEmpty(result)) {
            for (TaskDetailResultDTO detailResultDTO : result) {
                if (TableStatusEnum.STATUS_10.getCode().equals(detailResultDTO.getTaskStatus())) {
                    return detailResultDTO;
                }
            }
            return result.get(result.size() - 1);
        }
        return null;
    }

    /**
     * <p>
     * 提车首页-根据任务获取任务明细信息
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public TaskDetailResultDTO getTaskDetail(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            TaskDetailResultDTO detailQuick = getDetailQuick(dto);
            String send = exceptionToOTMService.isSend(detailQuick.getVin(), detailQuick.getOriginName());
            if (StringUtils.isNotBlank(send)){
                detailQuick.setIsCanSend(send);
            }
            return detailQuick;
        } else {
            TaskDetailResultDTO detailNorma = getDetailNormal(dto, loginUser);
            String send = exceptionToOTMService.isSend(detailNorma.getVin(), detailNorma.getOriginName());
            if (StringUtils.isNotBlank(send)){
                detailNorma.setIsCanSend(send);
            }
            return detailNorma;
        }
    }

    private TaskDetailResultDTO getDetailQuick(TaskControllerParamDTO dto) {
        String releaseId = dto.getId();
        if (StringUtils.isBlank(releaseId)) {
            throw new BaseException("运单明细ID不能为空");
        }
        OtmOrderRelease orderRelease = releaseService.selectById(releaseId);
        if (orderRelease == null) {
            throw new BaseException("未查询到运单id" + releaseId + "的运单信息");
        }
        TaskDetailResultDTO result = new TaskDetailResultDTO();
        result.setTaskNode(TableStatusEnum.STATUS_0.getCode());
        result.setTaskCreate(new Date());
        result.setTaskStart(new Date());
        result.setBindTime(new Date());
        result.setQrCode(orderRelease.getQrCode());
        result.setReleaseId(String.valueOf(orderRelease.getId()));
        result.setVehicle(orderRelease.getStanVehicleType());
        result.setDispatchNo(orderRelease.getShipmentGid());
        result.setOrderReleaseGid(orderRelease.getReleaseGid());
        result.setOriginCode(orderRelease.getOriginLocationGid());
        result.setOriginName(orderRelease.getOriginLocationName());
        result.setDestCode(orderRelease.getDestLocationGid());
        result.setDestName(orderRelease.getDestLocationName());
        result.setOrderDestAddress(orderRelease.getOrderDestAddress());
        result.setVin(orderRelease.getVin());
        result.setOrderNo(orderRelease.getCusOrderNo());
        result.setWayBillNo(orderRelease.getReleaseGid());
        result.setTaskType(TableStatusEnum.STATUS_0.getCode());
        result.setStanVehicleType(orderRelease.getStanVehicleType());
        result.setOtmStatus(orderRelease.getStatus());
        result.setModifiedVehicleType(orderRelease.getModifiedVehicleType());
        return result;
    }

    private TaskDetailResultDTO getDetailNormal(TaskControllerParamDTO dto, User loginUser) {
        dto.setUserCode(loginUser.getCode());
        String taskId = dto.getId();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        HashMap<String, Object> queryParam = Maps.newHashMap();
        queryParam.put("taskId", taskId);
        queryParam.put("status50", TableStatusEnum.STATUS_50.getCode());
        queryParam.put("start", 0);
        queryParam.put("end", 1);
        List<TaskDetailResultDTO> result = baseMapper.getTaskDetail(queryParam);
        Wrapper<OpDeliveryPoint> opDeliveryPointWrapper=new EntityWrapper<>();
        opDeliveryPointWrapper.eq("code", result.get(0).getOriginName());
        OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectOne(opDeliveryPointWrapper);
        if (CollectionUtils.isEmpty(result)) {
            throw new BaseException("未查询到任务id" + taskId + "的任务信息");
        }
        result.get(0).setPointId(opDeliveryPoint.getId());
        return result.get(0);
    }

    /**
     * <p>
     * 提车任务开始任务,绑定司机
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updatePickTask(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        dto.setDriverName(loginUser.getName());
        dto.setDriverPhone(loginUser.getMobile());
        String taskId = dto.getTaskId();
        String taskType = dto.getTaskType();

        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        OpTask task = baseMapper.selectById(taskId);
        if (!TableStatusEnum.STATUS_30.getCode().equals(task.getType())) {
            throw new BaseException("任务id:" + taskId + "任务类型不匹配!");
        }
        if (task.getStatus().equals(TableStatusEnum.STATUS_20.getCode()) ||
                task.getStatus().equals(TableStatusEnum.STATUS_30.getCode())) {
            throw new BaseException("任务状态为:" + task.getStatus() + "不支持此操作!");
        }
        HashMap<String,Object> param=new HashMap<>();
        param.put("driverPhone",dto.getDriverPhone());
        param.put("taskType",taskType);
        param.put("status",TableStatusEnum.STATUS_20.getCode());
        param.put("pointId",dto.getPointId());
        sysConfigService.timeConfig(param);
        // 获取运单信息
        OtmOrderRelease release = setReleaseAndStatusLog(loginUser, taskId, task);
        updateTaskPick(dto, task);
        // 回传OTM
        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(
                    taskId,
                    release.getReleaseGid(),
                    InterfaceEventEnum.OR_FIND.getCode(),
                    release.getShipmentGid(), "开始提车回传OTM");
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                //记录日志
                integrationService.insertExportLog(taskId,
                        event,
                        res,
                        "开始提车回传OTM",
                        InterfaceEventEnum.OR_FIND.getCode());
            }
        }).start();
        //更新运单表的时间
        this.setReleaseShipDate(release.getId(),loginUser.getName());
        //更新指令状态
        this.setShipmentStatus(release.getShipmentGid());
    }

    /**
     * 更新指令状态
     * @param shipmentGid
     */
    private void setShipmentStatus (String shipmentGid) {
        EntityWrapper<OtmOrderRelease> oorEW = new EntityWrapper<>();
        oorEW.eq("shipment_gid", shipmentGid);
        oorEW.isNull("ship_date");
        oorEW.ne("status", TableStatusEnum.STATUS_50.getCode());
        int notShipCount = otmOrderReleaseService.selectCount(oorEW);
        if (notShipCount == 0) {
            //明细已经全部发运/运抵
            OtmShipment os = new OtmShipment();
            os.setStatus(TableStatusEnum.STATUS_BS_DISPATCH.getCode());
            EntityWrapper<OtmShipment> shipmentEW = new EntityWrapper<>();
            shipmentEW.eq("shipment_gid",shipmentGid);
            shipmentEW.ne("status",TableStatusEnum.STATUS_50.getCode());
            shipmentService.update(os,shipmentEW);
        }
    }

    private void setReleaseShipDate (Long id, String name) {
        if (StringUtils.isNotEmpty(String.valueOf(id))) {
            OtmOrderRelease otmOrderRelease = new OtmOrderRelease();
            otmOrderRelease.setShipDate(new Date());
            otmOrderRelease.setRealShipDate(new Date());
            otmOrderRelease.setShipUser(name);
            EntityWrapper<OtmOrderRelease> ew = new EntityWrapper();
            ew.eq("id", id);
            otmOrderReleaseMapper.update(otmOrderRelease, ew);
        }
    }

    private OtmOrderRelease setReleaseAndStatusLog(User loginUser, String taskId, OpTask task) {
        EntityWrapper<OtmOrderRelease> ew = new EntityWrapper<>();
        ew.eq("release_gid", task.getWaybillNo())
                .ne("status", TableStatusEnum.STATUS_50.getCode());
        List<OtmOrderRelease> releaseList = releaseService.selectList(ew);
        if (CollectionUtils.isEmpty(releaseList)) {
            throw new BaseException("未查询到taskId:" + taskId + "的运单信息");
        }
        if (releaseList.size() > 1) {
            throw new BaseException("查询到taskId:" + taskId + "多条运单信息");
        }
        OtmOrderRelease release = releaseList.get(0);
        OtmOrderRelease orderRelease = new OtmOrderRelease();
        orderRelease.setId(release.getId());
        orderRelease.setStatus(TableStatusEnum.STATUS_WMS_PICKUP.getCode());
        releaseService.updateById(orderRelease);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(String.valueOf(release.getId()));
        statusLog.setStatus(TableStatusEnum.STATUS_WMS_PICKUP.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_WMS_PICKUP.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
        return release;
    }

    private void updateTaskPick(TaskControllerParamDTO dto, OpTask task) {
        task.setId(dto.getTaskId());
        task.setDriverCode(dto.getDriverCode());
        task.setDriverName(dto.getDriverName());
        task.setDriverPhone(dto.getDriverPhone());
        task.setStatus(TableStatusEnum.STATUS_20.getCode());
        task.setStartTime(new Date());
        task.setGmtModified(null);
        task.setUserModified(dto.getDriverCode());
        baseMapper.updateById(task);
        OpTask oldTask = baseMapper.selectById(dto.getTaskId());
        EntityWrapper<OpTask> ew = new EntityWrapper<>();
        ArrayList<String> types = Lists.newArrayList();
        types.add(TableStatusEnum.STATUS_20.getCode());
        types.add(TableStatusEnum.STATUS_10.getCode());
        ew.in("type", types)
                .in("status", types)
                .eq("dispatch_no", oldTask.getDispatchNo())
                .eq("waybill_no", oldTask.getWaybillNo());
        OpTask needFinish = new OpTask();
        needFinish.setStatus(TableStatusEnum.STATUS_30.getCode());
        needFinish.setUserModified("auto");
        baseMapper.update(needFinish, ew);

    }


    /**
     * <p>
     * 移车任务-完成移车
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updateMoveTask(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        dto.setDriverPhone(loginUser.getMobile());
        dto.setDriverName(loginUser.getName());
        String taskId = dto.getTaskId();
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类别不能为空!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("taskId", taskId);
        params.put("taskType", taskType);
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        List<TaskDetailResultDTO> detailResultDTOList = baseMapper.getTaskDetail(params);
        if (CollectionUtils.isEmpty(detailResultDTOList)) {
            throw new BaseException("未查询到taskId:" + taskId + "的移车任务,请确认!");
        }
        if (detailResultDTOList.size() > 1) {
            throw new BaseException("查询到taskId:" + taskId + "的多条移车任务!");
        }
        TaskDetailResultDTO detailDTO = detailResultDTOList.get(0);
        if (TableStatusEnum.STATUS_30.getCode().equals(detailDTO.getTaskStatus())) {
            throw new BaseException("查询到taskId:" + taskId + "任务已经完成,无需重复操作!");
        }
        HashMap<String,Object> param=new HashMap<>();
        param.put("driverPhone",dto.getDriverPhone());
        param.put("taskType",taskType);
        param.put("status",TableStatusEnum.STATUS_30.getCode());
        param.put("pointId",dto.getPointId());
        sysConfigService.timeConfig(param);
        updateTaskMove(dto);
        //回写运单状态
        setReleaseAndStatusLog(loginUser, detailDTO);

        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(
                    taskId,
                    detailDTO.getOrderReleaseGid(),
                    InterfaceEventEnum.OR_FIND.getCode(),
                    detailDTO.getDispatchNo(), "移车完成回传OTM");
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                //记录日志
                integrationService.insertExportLog(taskId, event, res, "移车完成回传OTM",
                        InterfaceEventEnum.OR_FIND.getCode());
            }
        }).start();
    }

    private void updateTaskMove(TaskControllerParamDTO dto) {
        OpTask task = new OpTask();
        task.setStatus(TableStatusEnum.STATUS_30.getCode());
        task.setStartTime(new Date());
        task.setFinishTime(new Date());
        task.setUserModified(dto.getDriverCode());
        task.setDriverCode(dto.getDriverCode());
        task.setDriverName(dto.getDriverName());
        task.setDriverPhone(dto.getDriverPhone());
        task.setGmtModified(new Date());
        task.setId(dto.getTaskId());
        baseMapper.updateById(task);
    }

    private void setReleaseAndStatusLog(User loginUser, TaskDetailResultDTO detailDTO) {
        OtmOrderRelease release = new OtmOrderRelease();
        release.setStatus(TableStatusEnum.STATUS_WMS_MOVE.getCode());
        release.setId(Long.valueOf(detailDTO.getReleaseId()));
        releaseService.updateById(release);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(detailDTO.getReleaseId());
        statusLog.setStatus(TableStatusEnum.STATUS_WMS_MOVE.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_WMS_MOVE.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
    }


    /**
     * <p>
     * 个人任务
     * </p>
     */
    @Override
    public ResultDTOWithPagination<List<TaskResultDTO>> getMyTaskByType(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        String driverCode = dto.getDriverCode();
        String taskType = dto.getTaskType();
        int pageNo = dto.getPageNo();
        if (pageNo < 1) {
            throw new BaseException("页码不正确!");
        }
        if (StringUtils.isBlank(driverCode)) {
            throw new BaseException("司机编码不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("查询任务类型不能为空!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("startOrFinish", taskType);
        params.put("driverCode", driverCode);
        params.put("userId",loginUser.getId());
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("orderBy", "c.gmt_create desc,c.type asc,c.id desc");
        params.put("start", dto.getStartIndex());
        params.put("end", dto.getPageSize());
        params.put("pointId", dto.getPointId());
        List<TaskResultDTO> list = baseMapper.selectTaskStartOrFinishByParam(params);
        int count = baseMapper.countTaskStartOrFinishByParam(params);
        ResultDTOWithPagination<List<TaskResultDTO>> result = new ResultDTOWithPagination<>();
        PageVo pageVo = new PageVo();
        pageVo.setPageNo(pageNo);
        pageVo.setPageSize(dto.getPageSize());
        pageVo.setTotalRecord(count);
        result.setPageVo(pageVo);
        result.setData(list);
        return result;
    }

    @Override
    public Page<TaskResultDTO> queryTaskList(Page<TaskResultDTO> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<TaskResultDTO> ew = buildWrapper(condition);
        List<TaskResultDTO> dtoList = baseMapper.selectTaskInfoByPage(page, ew);
        page.setRecords(dtoList);
        return page;
    }

    @Override
    public List<TaskResultDTO> exportTaskData(Map<String, Object> condition) {
        Wrapper<TaskResultDTO> ew = buildWrapper(condition);
        List<TaskResultDTO> dtoList = baseMapper.selectTaskInfo(ew);
        return dtoList;
    }

    public Wrapper<TaskResultDTO> buildWrapper(Map<String, Object> condition) {
        Wrapper<TaskResultDTO> ew = new EntityWrapper<>();
        if (condition != null) {
            if (condition.containsKey("taskType") && Objects.nonNull(condition.get("taskType"))) {
                ew.eq("type", condition.get("taskType"));
            }
            if (condition.containsKey("taskStatus") && Objects.nonNull(condition.get("taskStatus"))) {
                ew.eq("taskStatus", condition.get("taskStatus"));
            }
            if (condition.containsKey("orderNo") && Objects.nonNull(condition.get("orderNo"))) {
                ew.like("cus_order_no", condition.get("orderNo").toString());
            }
            if (condition.containsKey("driverName") && Objects.nonNull(condition.get("driverName"))) {
                ew.like("driver_name", condition.get("driverName").toString());
            }
            if (condition.containsKey("startAddr") && Objects.nonNull(condition.get("startAddr"))) {
                ew.like("origin_location_gid", condition.get("startAddr").toString());
            }
            if (condition.containsKey("startDate") && Objects.nonNull(condition.get("startDate"))) {
                ew.ge("start_time", condition.get("startDate").toString());
            }
            if (condition.containsKey("endDate") && Objects.nonNull(condition.get("endDate"))) {
                ew.le("start_time", condition.get("endDate").toString());
            }
            if (condition.containsKey("pointId") && Objects.nonNull(condition.get("pointId"))) {
                OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(condition.containsKey("pointId"));
                ew.eq("origin_location_gid", opDeliveryPoint.getCode());
            }
            if (condition.containsKey("vin") && Objects.nonNull(condition.get("vin"))) {
                List<String> vins = Arrays.asList(CommonMethod.setVins((String) condition.get("vin")));
                ew.andNew().in("vin", vins).or().like("vin", condition.get("vin").toString());
            }
        }
        ew.ne("otmStatus", TableStatusEnum.STATUS_50.getCode());
        ew.orderBy("waybill_no", false);
        ew.orderBy("type");
        ew.orderBy("gmt_create");
        return ew;
    }

    private void insertAndGetTask(String userCode,
                                  SnowFlakeId flakeId,
                                  ArrayList<OpTask> taskBatch,
                                  List<TaskResultDTO> resultData,
                                  TaskReleaseResultDTO selectDTO,
                                  String code) {
        //查询本地
        HashMap<String, Object> selectMap = Maps.newHashMap();
        selectMap.put("dispatch_no", selectDTO.getAttribute16());
        selectMap.put("waybill_no", selectDTO.getOrderReleaseGid());
        selectMap.put("type", code);
        List<OpTask> tasks = baseMapper.selectByMap(selectMap);
        if (CollectionUtils.isEmpty(tasks)) {
            //未查询到对应的类型任务
            OpTask task = getOpTask(userCode, selectDTO, flakeId, code);
            taskBatch.add(task);
            getResultData(userCode, resultData, selectDTO, task);
        } else {
            if (tasks.size() > 1) {
                throw new BaseException("运单:" + selectDTO.getOrderReleaseGid() +
                        ",指令:" + selectDTO.getAttribute16() + "存在多条移车任务");
            }
            getResultData(userCode, resultData, selectDTO, tasks.get(0));
        }
    }


    private void getResultData(String userCode,
                               List<TaskResultDTO> resultData,
                               TaskReleaseResultDTO resultDTO,
                               OpTask task) {
        TaskResultDTO resultTask = new TaskResultDTO();
        resultTask.setTaskId(task.getId());
        resultTask.setOriginCode(resultDTO.getSourceLocationGid());
        resultTask.setOriginName(resultDTO.getSourceLocationName());
        resultTask.setDestCode(resultDTO.getDestLocationGid());
        resultTask.setDestName(resultDTO.getDestLocationName());
        resultTask.setTaskStatus(task.getStatus());
        resultTask.setTaskType(task.getType());
        resultTask.setOrderNo(resultDTO.getAttribute1());
        resultTask.setWayBillNo(resultDTO.getOrderReleaseGid());
        resultTask.setVin(resultDTO.getAttribute7());
        resultTask.setUserCode(userCode);
        resultData.add(resultTask);
    }


    private OpTask getOpTask(String userCode,
                             TaskReleaseResultDTO resultDTO,
                             SnowFlakeId flakeId,
                             String statusCode) {
        OpTask task = new OpTask();
        task.setId(String.valueOf(flakeId.nextId()));
        task.setDispatchNo(resultDTO.getAttribute16()); //指令号取release运输指令号
        task.setWaybillNo(resultDTO.getOrderReleaseGid());//运单号取release系统单号
        task.setType(statusCode);
        task.setGmtCreate(new Date());
        task.setStatus(TableStatusEnum.STATUS_10.getCode());
        task.setGmtModified(new Date());
        task.setUserCreate(userCode);
        return task;
    }

    @Override
    public List<TaskResultDTO> queryDriverTask() {
        Map<String,Object> map = new HashMap<>();
        map.put("appid", properties.getHcmAppid());
        map.put("secret",properties.getSecret());
        String getAccessToken;
        try {
            getAccessToken = HttpRequestUtil.sendPostJSONNoContentType(properties.getHcmUrl()+properties.getGetAccessTokenUrl(),properties.getSocketTimeOut(), map, null);
        }catch (Exception e){
            LOGGER.error("获取token url:{},param:{}  超时异常:{}", properties.getHcmUrl()+properties.getGetAccessTokenUrl(), map, e);
            throw new BaseException("获取token异常");
        }
        if (StringUtils.isNotBlank(getAccessToken)) {
            JSONObject jsonObject = JSONObject.parseObject(getAccessToken);
            if (jsonObject.getInteger("errcode")==1) {
                JSONObject JSONObjectData = JSONObject.parseObject(jsonObject.getString("data"));
                String token = JSONObjectData.getString("token");
                List<TaskResultDTO> taskResultDTOS = baseMapper.queryDriverTask();
                Map<String,Object> addUserParam = new HashMap<>();
                addUserParam.put("TableId","Hxr_txltcb");
                SimpleDateFormat time=new SimpleDateFormat("yyyy-MM-dd");
                SimpleDateFormat yearMonth=new SimpleDateFormat("yyyy-MM");
                taskResultDTOS.forEach(taskResultDTO -> {
                    try {
                        Map<String,Object> queryUserParam = new HashMap<>();
                        queryUserParam.put("SeachText", taskResultDTO.getDriverPhone());
                        String queryUserRestul = HttpRequestUtil.sendPostJSONNoContentType(properties.getHcmUrl() + properties.getQueryUserUrl()+token, properties.getSocketTimeOut(), queryUserParam, null);
                        if (StringUtils.isNotBlank(queryUserRestul)) {
                            JSONObject queryUserJson = JSONObject.parseObject(queryUserRestul);
                            if (queryUserJson.getInteger("errcode")==1 && Objects.nonNull(queryUserJson.getJSONArray("data"))) {
                                Object data = queryUserJson.getJSONArray("data").get(0);
                                JSONObject jsonObject1 = JSONObject.parseObject(data.toString());
                                addUserParam.put("AccountId",jsonObject1.getString("AccountId"));
                                addUserParam.put("UserName", jsonObject1.getString("UserName"));
                                addUserParam.put("PersonNo", jsonObject1.getString("PersonNo"));
                                addUserParam.put("ny", yearMonth.format(new Date()));
                                addUserParam.put("rq", time.format(new Date()));
                                addUserParam.put("xl", taskResultDTO.getOriginCode()+"-"+taskResultDTO.getDestCode());
                                addUserParam.put("sl", taskResultDTO.getCount());
                                addUserParam.put("tc", 0);
                                HttpRequestUtil.sendPostJSONNoContentType(properties.getHcmUrl() + properties.getAddUserUrl()+token, properties.getSocketTimeOut(), addUserParam, null);
                            }else{
                                LOGGER.error("查询人员信息异常 url:{},param:{}  异常:{}", properties.getHcmUrl()+properties.getQueryUserUrl(), queryUserParam, queryUserJson.getString("errmsg"));
                            }
                        }
                    }catch(Exception e){
                        LOGGER.error("增加人员子集信息 url:{},param:{}  超时异常:{}", properties.getHcmUrl()+properties.getGetAccessTokenUrl(), addUserParam, e);
                        throw new BaseException("增加人员子集信息异常");
                    }
                });


            }else{
                throw new BaseException(jsonObject.getString("errmsg"));
            }
        }
        return null;
    }
}
